<template>
	<transition name="message-fade">
		<div class="message-box" @mouseenter="clearTimer" @mouseleave="startTimer" v-if="visible">
			<div :class="['message', type && !iconClass ? `message-${type}` : '', center ? 'center' : '', showClose ? 'closable' : '', customClass]">
				<i :class="iconClass" v-if="iconClass"></i>
				<i :class="typeClass" v-else></i>
				<slot>
					<p v-if="!dangerouslyUseHTMLString" class="message-content">{{ message }}</p>
					<p v-else v-html="message" class="message-content"></p>
				</slot>
				<i v-if="showClose" class="message-close-btn icon-close" @click="close"></i>
			</div>
		</div>
	</transition>
</template>

<script>
const typeMap = {
	success: 'success',
	info: 'info',
	warning: 'warning',
	error: 'error'
};
export default {
	data() {
		return {
			visible: false,
			message: '',
			duration: 3,
			type: 'info',
			iconClass: '',
			customClass: '',
			onClose: null,
			showClose: false,
			closed: false,
			timer: null,
			dangerouslyUseHTMLString: false,
			center: false
		};
	},
	computed: {
		typeClass() {
			return this.type && !this.iconClass ? `message-icon icon-${typeMap[this.type]}` : '';
		}
	},
	watch: {
		closed(newVal) {
			if (newVal) {
				this.visible = false;
				this.$el.addEventListener('transitionend', this.destroyElement);
			}
		}
	},
	methods: {
		destroyElement() {
			this.$el.removeEventListener('transitionend', this.destroyElement);
			this.$destroy(true);
			this.$el.parentNode && this.$el.parentNode.removeChild(this.$el);
		},
		close() {
			this.closed = true;
			if (typeof this.onClose === 'function') {
				this.onClose(this);
			}
		},
		clearTimer() {
			// 鼠标移动上，不取消定时任务
			// clearTimeout(this.timer);
		},
		startTimer() {
			if (this.duration > 0) {
				this.timer = setTimeout(() => {
					if (!this.closed) {
						this.close();
					}
				}, this.duration * 1000);
			}
		},
		keydown(e) {
			if (e.keyCode === 27) {
				// esc关闭消息
				if (!this.closed) {
					this.close();
				}
			}
		}
	},
	mounted() {
		this.startTimer();
		document.addEventListener('keydown', this.keydown);
	},
	beforeDestroy() {
		document.removeEventListener('keydown', this.keydown);
	}
};
</script>

<style scoped>
.message {
	background-color: #edf2f3;
	display: flex;
	padding: 10px 16px;
	margin: 0 auto;
	align-items: center;
	overflow: hidden;
	max-width: 70%;
}
.message-box {
	margin: 0 auto;
	position: fixed;
	left: 50%;
	top: 20px;
	transform: translateX(-50%);
	transition: opacity 0.3s, transform 0.4s;
	overflow: hidden;
	display: flex;
	align-items: center;
	z-index: 999999999;
	width: 100%;
}
.message-icon {
	width: 15px;
	height: 15px;
	border-radius: 100%;
	background: #fff;
	display: inline-block;
	margin-right: 4px;
	padding: 0 4px;
}
.icon-success {
	background: url('../../assets/message/success.png') no-repeat center center;
	background-size: auto 100%;
}
.icon-error {
	background: url('../../assets/message/error.png') no-repeat center center;
	background-size: auto 100%;
}
.icon-info {
	background: url('../../assets/message/info.png') no-repeat center center;
	background-size: auto 100%;
}
.icon-warning {
	background: url('../../assets/message/warning.png') no-repeat center center;
	background-size: auto 100%;
}
.message-success {
	background: #f2f8ec;
	border-color: #e4f2da;
}
.message-content {
	color: #7ebe50;
	margin: 0;
}
.message-error {
	background: #fcf0f0;
	border-color: #f9e3e2;
}
.message-content {
	color: #e57470;
	margin: 0;
}
.message-warning {
	background: #fcf6ed;
	border-color: #f8ecda;
}
.message-content {
	color: #dca450;
	margin: 0;
}
.message-info {
	background: #eef2fb;
	border-color: #ebeef4;
}
.message-content {
	color: #919398;
	margin: 0;
}
.message-fade-enter,
.message-fade-leave-active {
	opacity: 0;
	transform: translate(-50%, -100%);
}
</style>
